﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.CompilerServices;
using OpenCvSharp;

namespace Project4
{
    class Program
    {
        /// <summary>
        /// 提取图像曲线集合
        /// </summary>
        /// <param name="src">原图，只支持24位图像</param>
        /// <returns></returns>
        static List<Point[]> findLines(Mat src)
        {
            if (src.Channels() != 3) return new List<Point[]>();
            List<Point[]> lines = new List<Point[]>();

            Mat hsv = new Mat();    //HSV色彩空间图像
            Mat thre = new Mat();   //二值化图像

            //将原图BGR色彩空间转换为HSV色彩空间
            Cv2.CvtColor(src, hsv, ColorConversionCodes.BGR2HSV_FULL);
            //二值化，保留H∈[0, 255],S∈[0, 10],V∈[180， 210]的像素（即灰色像素），其余部分为黑色
            Cv2.InRange(hsv, new Scalar(0, 0, 180), new Scalar(255, 10, 210), thre);

            //提取二值图的轮廓
            Point[][] contours;
            HierarchyIndex[] indexes;
            Cv2.FindContours(thre, out contours, out indexes, RetrievalModes.List, ContourApproximationModes.ApproxNone);

            //每个轮廓提取一半即为曲线的路径。当然这种做法不是很严谨，存在一定误差，若误差能够容忍，且不存在曲线交点的情况，可以使用这种方式
            for (int i = 0; i < contours.Length; i++)
            {
                Point[] temp = new Point[contours[i].Length / 2];
                Array.Copy(contours[i], temp, contours[i].Length / 2);
                lines.Add(temp);
            }

            return lines;
        }
        static void Main(string[] args)
        {
            Mat src = Cv2.ImRead("src.png", ImreadModes.Color);
            Mat dst = Mat.Zeros(src.Size(), MatType.CV_8UC1);

            //提取线条集合
            List<Point[]> lines = findLines(src);

            //绘制每个线条
            for (int i = 0; i < lines.Count; i++)
                for (int j = 0; j < lines[i].Length; j++)
                    Cv2.Line(dst, lines[i][j], lines[i][j], Scalar.All(255));

            //保存结果图像
            Cv2.ImWrite("dst.png", dst);
            Console.WriteLine("Hello World!");
        }
    }
}
